/*
 * Concepts.java
 *
 * Created on 1 de Dezembro de 2007, 16:46
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.ontoscheduler.concepts;

import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.ObjectProperty;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import java.util.Collection;

import java.util.Iterator;
import java.util.UUID;

/**
 *
 * @author joaoolavo
 */
abstract public class Concepts {
    public String ns = "http://www.ufo.org/ufo-c/commitments.owl#";
    public OntClass concept = null;
    
    protected static int DATATYPE_PROPERTY = 0;
    protected static int OBJECT_PROPERTY = 1;
       
    /**
     * Creates a new instance of Concepts
     */
    public Concepts() {
    }
    
    protected void setConcept(OntModel mod, String conceptName){
        concept = mod.getOntClass(ns + conceptName);
    }
    
    public Individual addIndividual(){
        Individual i = concept.createIndividual();
        return i;
    }
    
    public Individual addIndividual(String name){
        String name_uri = stripWhiteSpaces(name) + UUID.randomUUID().toString();
//        String nome_label = stripAllSpaces(name);
        Individual i = concept.createIndividual(ns + name_uri);
        setIndividualName(i, name);
        return i;
    }

    public Individual getIndividual(String nome){
        for(Iterator i = listIndividuals(); i.hasNext();){
            Individual ind = (Individual) i.next();
            if(ind.getLocalName().equals(nome))
                return ind;
        }
        return null;
    }
    
    public Iterator listIndividuals(){
        return concept.listInstances();
    }
    
    public void setIndividualName(Individual i, String name){
        String indName = getIndividualName(i);
        if(indName != null)
            i.removeLabel(indName, null);
        i.setLabel(name, null);
    }
    
    public String getIndividualName(Individual i){
        Iterator n = i.listLabels(null);
        if(n.hasNext())
            return n.next().toString();
        else
            return null;
    }

    public int addPropertyValues(String propertyName, Individual ind, Collection values, int kind){
        // Removing this individual from the inverse invididual.
        if(kind == OBJECT_PROPERTY){
            ObjectProperty p = concept.getOntModel().getObjectProperty(ns + propertyName);
            Iterator propValues = ind.listPropertyValues(p);
            while(propValues.hasNext()){
                OntProperty p_inv = p.getInverse();
                RDFNode node = (RDFNode) propValues.next();
                Resource res = (Resource) node;
                OntModel ontmodel = (OntModel) res.getModel();
                Individual i = ontmodel.getIndividual(res.getURI());
                i.removeProperty(p_inv, ind.getOntModel().getRDFNode(ind.asNode()));
            }
            ind.removeAll(p);
        }
        
        for(Iterator it = values.iterator(); it.hasNext();){
            addPropertyValue(propertyName, ind, it.next(), kind);
        }
        
        return 0;
    }
    
    public int addPropertyValue(String propertyName, Individual ind, Object value, int kind){
//        int card_exactly = getCardinality(ind, propertyName, CARD_EXACTLY);
        
        if(kind == DATATYPE_PROPERTY){
            DatatypeProperty p = concept.getOntModel().getDatatypeProperty(ns + propertyName);
            Literal l = concept.getOntModel().createTypedLiteral(value);
            ind.addProperty(p, l);
        }
        else{
            if(kind == OBJECT_PROPERTY){
                    Individual v = (Individual) value;
                    ObjectProperty p = concept.getOntModel().getObjectProperty(ns + propertyName);
                    OntProperty p_inv = p.getInverse();
                    ind.addProperty(p, v);
        //            VERIFICAR A CARDINALIDADE DA INVERSA!!!!!
                    v.addProperty(p_inv, ind); // !!!!!!!!!!!!!!!!!!!! **************** !!!!!!!!!!!!!!!!!!!!!!!!
        //            VERIFICAR A CARDINALIDADE DA INVERSA!!!!!
            }
        }
        
        return 0;
    }
    
    public Iterator getPropertyValues(String propertyName, Individual ind){
        Property p = concept.getOntModel().getProperty(ns + propertyName);
        return ind.listPropertyValues(p);
    }
    
    private static String stripWhiteSpaces(String str){
        String ret = "";
            for (int i = 0; i < str.length(); i++){
                if (str.charAt(i) != ' ')
                     ret += str.charAt(i);
            }
        return ret;  
    }  
}

//    private int getCardinality(OntModel model, String concept, String property, int kind) {
//        OntClass oc = model.getOntClass(ns+concept);
//        if (oc!=null) {
//            Iterator i = oc.listSuperClasses();
//            while(i.hasNext()) {
//                OntClass oclass = (OntClass)i.next();
//                if (oclass.isRestriction()) {
//                    Restriction rest = oclass.asRestriction();
//                    OntProperty prop = rest.getOnProperty();
//                    if ( ( prop != null ) && ( prop.getLocalName().equals(property) ) ) {
//                        if( ( kind == 1 ) && ( rest.isCardinalityRestriction()) ) {
//                            //System.out.println(rest.asCardinalityRestriction().getCardinality());
//                            return rest.asCardinalityRestriction().getCardinality();
//                        }
//                        if( ( kind == 2 ) && (rest.isMaxCardinalityRestriction()) ) {
//                            //System.out.println(rest.asMaxCardinalityRestriction().getMaxCardinality());
//                            return rest.asMaxCardinalityRestriction().getMaxCardinality();
//                        }
//                        if( ( kind == 3 ) && (rest.isMinCardinalityRestriction()) ) {
//                            //System.out.println(rest.asMinCardinalityRestriction().getMinCardinality());
//                            return rest.asMinCardinalityRestriction().getMinCardinality();
//                        }
//                    }
//                }
//            }
//        }
//        return -1;
//    }